home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / binutils.7 / binutils / binutils-2.7 / ld / emultempl / pe.em < prev    next >
Encoding:
Text File  |  1996-07-04  |  20.1 KB  |  686 lines

  1. # This shell script emits a C file. -*- C -*-
  2. # It does some substitutions.
  3. cat >e${EMULATION_NAME}.c <<EOF
  4. /* For WINDOWS_NT */
  5. /* The original file generated returned different default scripts depending
  6.    on whether certain switches were set, but these switches pertain to the
  7.    Linux system and that particular version of coff.  In the NT case, we
  8.    only determine if the subsystem is console or windows in order to select
  9.    the correct entry point by default. */ 
  10.   
  11.  
  12. /* This file is part of GLD, the Gnu Linker.
  13.  
  14. This program is free software; you can redistribute it and/or modify
  15. it under the terms of the GNU General Public License as published by
  16. the Free Software Foundation; either version 2 of the License, or
  17. (at your option) any later version.
  18.  
  19. This program is distributed in the hope that it will be useful,
  20. but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22. GNU General Public License for more details.
  23.  
  24. You should have received a copy of the GNU General Public License
  25. along with this program; if not, write to the Free Software
  26. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  27.  
  28. #include "bfd.h"
  29. #include "sysdep.h"
  30. #include "bfdlink.h"
  31. #include "getopt.h"
  32. #include "ld.h"
  33. #include "ld.h"
  34. #include "ldmain.h"
  35. #include "ldgram.h"
  36. #include "ldexp.h"
  37. #include "ldlang.h"
  38. #include "ldemul.h"
  39. #include "ldlex.h"
  40. #include "ldmisc.h"
  41. #include "ldctor.h"
  42. #include "ldfile.h"
  43. #include "coff/internal.h"
  44. #include "../bfd/libcoff.h"
  45.  
  46. #define TARGET_IS_${EMULATION_NAME}
  47.  
  48. static void gld_${EMULATION_NAME}_set_symbols PARAMS ((void));
  49. static void gld_${EMULATION_NAME}_after_open PARAMS ((void));
  50. static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
  51. static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
  52. static boolean gld${EMULATION_NAME}_place_orphan
  53.   PARAMS ((lang_input_statement_type *, asection *));
  54. static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
  55. static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
  56.  
  57. #if 0 /* argument to qsort so don't prototype */
  58. static int sort_by_file_name PARAMS ((void *, void *));
  59. static int sort_by_section_name PARAMS ((void *, void *));
  60. #endif
  61. static lang_statement_union_type **sort_sections_1
  62.   PARAMS ((lang_statement_union_type **, lang_statement_union_type *, int,
  63.        int (*)()));
  64. static void sort_sections PARAMS ((lang_statement_union_type *));
  65.  
  66. static struct internal_extra_pe_aouthdr pe;
  67. static int dll;
  68.  
  69. static void
  70. gld_${EMULATION_NAME}_before_parse()
  71. {
  72.   ldfile_output_architecture = bfd_arch_${ARCH};
  73. }
  74.  
  75. /* PE format extra command line options.  */
  76.  
  77. /* Used for setting flags in the PE header. */
  78. #define OPTION_BASE_FILE        (300  + 1)
  79. #define OPTION_DLL            (OPTION_BASE_FILE + 1)
  80. #define OPTION_FILE_ALIGNMENT        (OPTION_DLL + 1)
  81. #define OPTION_IMAGE_BASE        (OPTION_FILE_ALIGNMENT + 1)
  82. #define OPTION_MAJOR_IMAGE_VERSION    (OPTION_IMAGE_BASE + 1)
  83. #define OPTION_MAJOR_OS_VERSION        (OPTION_MAJOR_IMAGE_VERSION + 1)
  84. #define OPTION_MAJOR_SUBSYSTEM_VERSION    (OPTION_MAJOR_OS_VERSION + 1)
  85. #define OPTION_MINOR_IMAGE_VERSION    (OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
  86. #define OPTION_MINOR_OS_VERSION        (OPTION_MINOR_IMAGE_VERSION + 1)
  87. #define OPTION_MINOR_SUBSYSTEM_VERSION    (OPTION_MINOR_OS_VERSION + 1)
  88. #define OPTION_SECTION_ALIGNMENT    (OPTION_MINOR_SUBSYSTEM_VERSION + 1)
  89. #define OPTION_STACK                    (OPTION_SECTION_ALIGNMENT + 1)
  90. #define OPTION_SUBSYSTEM                (OPTION_STACK + 1)
  91. #define OPTION_HEAP            (OPTION_SUBSYSTEM + 1)
  92.  
  93. static struct option longopts[] = {
  94.   /* PE options */
  95.     {"base-file", required_argument, NULL, OPTION_BASE_FILE},
  96.     {"dll", no_argument, NULL, OPTION_DLL},
  97.     {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
  98.     {"heap", required_argument, NULL, OPTION_HEAP}, 
  99.     {"image-base", required_argument, NULL, OPTION_IMAGE_BASE}, 
  100.     {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
  101.     {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
  102.     {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
  103.     {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
  104.     {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
  105.     {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
  106.     {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
  107.     {"stack", required_argument, NULL, OPTION_STACK},
  108.     {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
  109.    {NULL, no_argument, NULL, 0}
  110.   };
  111.  
  112.  
  113. /* PE/WIN32; added routines to get the subsystem type, heap and/or stack
  114.    parameters which may be input from the command line */
  115.  
  116. typedef struct {
  117.   void *ptr;
  118.   int size;
  119.   int value;
  120.   char *symbol;
  121.   int inited;
  122. } definfo;
  123.  
  124. #define D(field,symbol,def)  {&pe.field,sizeof(pe.field), def, symbol,0}
  125.  
  126. static definfo init[] =
  127. {
  128.   /* imagebase must be first */
  129. #define IMAGEBASEOFF 0
  130.   D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
  131. #define DLLOFF 1
  132.   {&dll, sizeof(dll), 0, "__dll__"},
  133.   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
  134.   D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
  135.   D(MajorOperatingSystemVersion,"__major_os_version__", 4),
  136.   D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
  137.   D(MajorImageVersion,"__major_image_version__", 1),
  138.   D(MinorImageVersion,"__minor_image_version__", 0),
  139.   D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
  140.   D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
  141.   D(Subsystem,"__subsystem__", 3),
  142.   D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x100000),
  143.   D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
  144.   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
  145.   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
  146.   D(LoaderFlags,"__loader_flags__", 0x0),
  147.   0
  148. };
  149.  
  150.  
  151. static void
  152. set_pe_name (name, val)
  153.      char *name;
  154.      long val;
  155. {
  156.   int i;
  157.   /* Find the name and set it. */
  158.   for (i = 0; init[i].ptr; i++)
  159.     {
  160.       if (strcmp (name, init[i].symbol) == 0)
  161.     {
  162.       init[i].value = val;
  163.       init[i].inited = 1;
  164.       return;
  165.     }
  166.     }
  167.   abort();
  168. }
  169.  
  170.  
  171. static void
  172. set_pe_subsystem ()
  173. {
  174.   int i;
  175.   static struct 
  176.     {
  177.       char *name ;
  178.       int value;
  179.     }
  180.   v[] =
  181.     {
  182.       {"native", 1},
  183.       {"windows",2},
  184.       {"console",3},
  185.       {"os2",5},
  186.       {"posix", 7},
  187.       {0,0}
  188.     };
  189.  
  190.   for (i = 0; v[i].name; i++)
  191.     {
  192.       if (!strcmp (optarg, v[i].name)) 
  193.     {
  194.       set_pe_name ("__subsystem__", v[i].value);
  195.       return;
  196.     }
  197.     }
  198.   einfo ("%P%F: invalid subsystem type %s\n", optarg);
  199. }
  200.  
  201.  
  202.  
  203. static void
  204. set_pe_value (name)
  205.      char *name;
  206.      
  207. {
  208.   char *end;
  209.   set_pe_name (name,  strtoul (optarg, &end, 0));
  210.   if (end == optarg)
  211.     {
  212.       einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
  213.     }
  214.  
  215.   optarg = end;
  216. }
  217.  
  218. static void
  219. set_pe_stack_heap (resname, comname)
  220.      char *resname;
  221.      char *comname;
  222. {
  223.   char *begin_commit;
  224.   char *end;
  225.  
  226.   set_pe_value (resname);
  227.   if (*optarg == ',')
  228.     {
  229.       optarg++;
  230.       set_pe_value (comname);
  231.     }
  232.   else if (*optarg)
  233.     {
  234.       einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
  235.     }
  236. }
  237.  
  238.  
  239.  
  240. static int
  241. gld_${EMULATION_NAME}_parse_args(argc, argv)
  242.      int argc;
  243.      char **argv;
  244. {
  245.   int longind;
  246.   int optc;
  247.   int prevoptind = optind;
  248.   int prevopterr = opterr;
  249.   int wanterror;
  250.   static int lastoptind = -1;
  251.  
  252.   if (lastoptind != optind)
  253.     opterr = 0;
  254.   wanterror = opterr;
  255.  
  256.   lastoptind = optind;
  257.  
  258.   optc = getopt_long_only (argc, argv, "-", longopts, &longind);
  259.   opterr = prevopterr;
  260.  
  261.   switch (optc)
  262.     {
  263.     default:
  264.       if (wanterror)
  265.     xexit (1);
  266.       optind =  prevoptind;
  267.       return 0;
  268.  
  269.     case OPTION_BASE_FILE:
  270.       link_info.base_file = (PTR) fopen (optarg, FOPEN_WB);
  271.       if (link_info.base_file == NULL)
  272.     {
  273.       fprintf (stderr, "%s: Can't open base file %s\n",
  274.            program_name, optarg);
  275.       xexit (1);
  276.     }
  277.       break;
  278.  
  279.       /* PE options */
  280.     case OPTION_HEAP: 
  281.       set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
  282.       break;
  283.     case OPTION_STACK: 
  284.       set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
  285.       break;
  286.     case OPTION_SUBSYSTEM:
  287.       set_pe_subsystem ();
  288.       break;
  289.     case OPTION_MAJOR_OS_VERSION:
  290.       set_pe_value ("__major_os_version__");
  291.       break;
  292.     case OPTION_MINOR_OS_VERSION:
  293.       set_pe_value ("__minor_os_version__");
  294.       break;
  295.     case OPTION_MAJOR_SUBSYSTEM_VERSION:
  296.       set_pe_value ("__major_subsystem_version__");
  297.       break;
  298.     case OPTION_MINOR_SUBSYSTEM_VERSION:
  299.       set_pe_value ("__minor_subsystem_version__");
  300.       break;
  301.     case OPTION_MAJOR_IMAGE_VERSION:
  302.       set_pe_value ("__major_image_version__");
  303.       break;
  304.     case OPTION_MINOR_IMAGE_VERSION:
  305.       set_pe_value ("__minor_image_version__");
  306.       break;
  307.     case OPTION_FILE_ALIGNMENT:
  308.       set_pe_value ("__file_alignment__");
  309.       break;
  310.     case OPTION_SECTION_ALIGNMENT:
  311.       set_pe_value ("__section_alignment__");
  312.       break;
  313.     case OPTION_DLL:
  314.       set_pe_name ("__dll__", 1);
  315.       break;
  316.     case OPTION_IMAGE_BASE:
  317.       set_pe_value ("__image_base__");
  318.       break;
  319.     }
  320.   return 1;
  321. }
  322.  
  323. static void
  324. gld_${EMULATION_NAME}_set_symbols()
  325. {
  326.   /* Run through and invent symbols for all the
  327.      names and insert the defaults. */
  328.   int j;
  329.   lang_statement_list_type *save;
  330.  
  331.   if (!init[IMAGEBASEOFF].inited)
  332.     init[IMAGEBASEOFF].value = init[DLLOFF].value
  333.       ? NT_DLL_IMAGE_BASE : NT_EXE_IMAGE_BASE;
  334.  
  335.   /* Glue the assignments into the abs section */
  336.   save = stat_ptr;
  337.  
  338.   stat_ptr = &(abs_output_section->children);
  339.  
  340.   for (j = 0; init[j].ptr; j++)
  341.     {
  342.       long val = init[j].value;
  343.       lang_add_assignment (exp_assop ('=' ,init[j].symbol, exp_intop (val)));
  344.       if (init[j].size == sizeof(short))
  345.     *(short *)init[j].ptr = val;
  346.       else if (init[j].size == sizeof(int))
  347.     *(int *)init[j].ptr = val;
  348.       else if (init[j].size == sizeof(long))
  349.     *(long *)init[j].ptr = val;
  350.       else    abort();
  351.     }
  352.   /* Restore the pointer. */
  353.   stat_ptr = save;
  354.   
  355.   if (pe.FileAlignment >
  356.       pe.SectionAlignment)
  357.     {
  358.       einfo ("%P: warning, file alignment > section alignment.\n");
  359.     }
  360. }
  361.  
  362. static void
  363. gld_${EMULATION_NAME}_after_open()
  364. {
  365.   /* Pass the wacky PE command line options into the output bfd */
  366.   struct internal_extra_pe_aouthdr *i;
  367.   if (!coff_data(output_bfd)->pe)
  368.     {
  369.       einfo ("%F%P: PE operations on non PE file.\n");
  370.     }
  371.  
  372.   pe_data(output_bfd)->pe_opthdr = pe;
  373.   pe_data(output_bfd)->dll = init[DLLOFF].value;
  374.  
  375. }
  376.  
  377. /* Callback functions for qsort in sort_sections. */
  378.  
  379. static int
  380. sort_by_file_name (a, b)
  381.      void *a;
  382.      void *b;
  383. {
  384.   lang_statement_union_type **ra = a;
  385.   lang_statement_union_type **rb = b;
  386.   return strcmp ((*ra)->input_section.ifile->filename,
  387.          (*rb)->input_section.ifile->filename);
  388. }
  389.  
  390. static int
  391. sort_by_section_name (a, b)
  392.      void *a;
  393.      void *b;
  394. {
  395.   lang_statement_union_type **ra = a;
  396.   lang_statement_union_type **rb = b;
  397.   return strcmp ((*ra)->input_section.section->name,
  398.          (*rb)->input_section.section->name);
  399. }
  400.  
  401. /* Subroutine of sort_sections to a contiguous subset of a list of sections.
  402.    NEXT_AFTER is the element after the last one to sort.
  403.    The result is a pointer to the last element's "next" pointer.  */
  404.  
  405. static lang_statement_union_type **
  406. sort_sections_1 (startptr, next_after, count, sort_func)
  407.      lang_statement_union_type **startptr,*next_after;
  408.      int count;
  409.      int (*sort_func) ();
  410. {
  411.   lang_statement_union_type **vec;
  412.   lang_statement_union_type *p;
  413.   int i;
  414.  
  415.   if (count == 0)
  416.     return startptr;
  417.  
  418.   vec = (lang_statement_union_type **)
  419.     alloca (count * sizeof (lang_statement_union_type *));
  420.  
  421.   for (p = *startptr, i = 0; i < count; i++, p = p->next)
  422.     vec[i] = p;
  423.  
  424.   qsort (vec, count, sizeof (vec[0]), sort_func);
  425.  
  426.   /* Fill in the next pointers again. */
  427.   *startptr = vec[0];
  428.   for (i = 0; i < count - 1; i++)
  429.     vec[i]->header.next = vec[i + 1];
  430.   vec[i]->header.next = next_after;
  431.   return &(vec[i]->header.next);
  432. }
  433.  
  434. /* Sort the .idata\$foo input sections of archives into filename order.
  435.    The reason is so dlltool can arrange to have the pe dll import information
  436.    generated correctly - the head of the list goes into dh.o, the tail into
  437.    dt.o, and the guts into ds[nnnn].o.  Note that this is only needed for the
  438.    .idata section.
  439.    FIXME: This may no longer be necessary with grouped sections.  Instead of
  440.    sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use
  441.    .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t.
  442.    This would have to be elaborated upon to handle multiple dll's
  443.    [assuming such an eloboration is possible of course].
  444.  
  445.    We also sort sections in '\$' wild statements.  These are created by the
  446.    place_orphans routine to implement grouped sections.  */
  447.  
  448. static void
  449. sort_sections (s)
  450.      lang_statement_union_type *s;
  451. {
  452.   for (; s ; s = s->next)
  453.     switch (s->header.type)
  454.       {
  455.       case lang_output_section_statement_enum:
  456.     sort_sections (s->output_section_statement.children.head);
  457.     break;
  458.       case lang_wild_statement_enum:
  459.     {
  460.       lang_statement_union_type **p = &s->wild_statement.children.head;
  461.  
  462.       /* Is this the .idata section?  */
  463.       if (s->wild_statement.section_name != NULL
  464.           && strncmp (s->wild_statement.section_name, ".idata", 6) == 0)
  465.         {
  466.           /* Sort any children in the same archive.  Run through all
  467.          the children of this wild statement, when an
  468.          input_section in an archive is found, scan forward to
  469.          find all input_sections which are in the same archive.
  470.          Sort them by their filename and then re-thread the
  471.          pointer chain. */
  472.  
  473.           while (*p)
  474.         {
  475.           lang_statement_union_type *start = *p;
  476.           if (start->header.type != lang_input_section_enum
  477.               || !start->input_section.ifile->the_bfd->my_archive)
  478.             p = &(start->header.next);
  479.           else
  480.             {
  481.               lang_statement_union_type *end;
  482.               int count;
  483.  
  484.               for (end = start, count = 0;
  485.                end && end->header.type == lang_input_section_enum
  486.                && (end->input_section.ifile->the_bfd->my_archive
  487.                    == start->input_section.ifile->the_bfd->my_archive);
  488.                end = end->next)
  489.             count++;
  490.  
  491.               p = sort_sections_1 (p, end, count, sort_by_file_name);
  492.             }
  493.         }
  494.           break;
  495.         }
  496.  
  497.       /* If this is a collection of grouped sections, sort them.
  498.          The linker script must explicitly mention "*(.foo\$)".
  499.          Don't sort them if \$ is not the last character (not sure if
  500.          this is really useful, but it allows explicitly mentioning
  501.          some \$ sections and letting the linker handle the rest).  */
  502.       if (s->wild_statement.section_name != NULL)
  503.         {
  504.           char *q = strchr (s->wild_statement.section_name, '\$');
  505.  
  506.           if (q && q[1] == 0)
  507.         {
  508.           lang_statement_union_type *end;
  509.           int count;
  510.  
  511.           for (end = *p, count = 0; end; end = end->next)
  512.             {
  513.               if (end->header.type != lang_input_section_enum)
  514.             abort ();
  515.               count++;
  516.             }
  517.           (void) sort_sections_1 (p, end, count, sort_by_section_name);
  518.         }
  519.           break;
  520.         }
  521.     }
  522.     break;
  523.       default:
  524.     break;
  525.       }
  526. }
  527.  
  528. static void  
  529. gld_${EMULATION_NAME}_before_allocation()
  530. {
  531.   extern lang_statement_list_type *stat_ptr;
  532.  
  533. #ifdef TARGET_IS_ppcpe
  534.   /* Here we rummage through the found bfds to collect toc information */
  535.   {
  536.     LANG_FOR_EACH_INPUT_STATEMENT (is)
  537.       {
  538.     ppc_process_before_allocation(is->the_bfd, &link_info);
  539.       }
  540.   }
  541.  
  542.   /* We have seen it all. Allocate it, and carry on */
  543.   ppc_allocate_toc_section (&link_info);
  544. #endif
  545.  
  546.   sort_sections (stat_ptr->head);
  547. }
  548.  
  549. /* Place an orphan section.  We use this to put sections with a '\$' in them
  550.    into the right place.  Any section with a '\$' in them (e.g. .text\$foo)
  551.    gets mapped to the output section with everything from the '\$' on stripped
  552.    (e.g. .text).
  553.    See the Microsoft Portable Executable and Common Object File Format
  554.    Specification 4.1, section 4.2, Grouped Sections.  */
  555.  
  556. /*ARGSUSED*/
  557. static boolean
  558. gld${EMULATION_NAME}_place_orphan (file, s)
  559.      lang_input_statement_type *file;
  560.      asection *s;
  561. {
  562.   const char *secname;
  563.   char *output_secname, *ps;
  564.   lang_output_section_statement_type *os;
  565.   lang_statement_list_type *ptr;
  566.   lang_statement_union_type *l;
  567.  
  568.   if ((s->flags & SEC_ALLOC) == 0)
  569.     return false;
  570.  
  571.   /* Don't process grouped sections unless doing a final link.
  572.      If they're marked as COMDAT sections, we don't want .text\$foo to
  573.      end up in .text and then have .text disappear because it's marked
  574.      link-once-discard.  */
  575.   if (link_info.relocateable)
  576.     return false;
  577.  
  578.   secname = bfd_get_section_name (s->owner, s);
  579.  
  580.   /* Everything from the '\$' on gets deleted so don't allow '\$' as the
  581.      first character.  */
  582.   if (*secname == '\$')
  583.     einfo ("%P%F: section %s has '\$' as first character\n", secname);
  584.   if (strchr (secname + 1, '\$') == NULL)
  585.     return false;
  586.  
  587.   /* Look up the output section.  The Microsoft specs say sections names in
  588.      image files never contain a '\$'.  Fortunately, lang_..._lookup creates
  589.      the section if it doesn't exist.  */
  590.   output_secname = buystring (secname);
  591.   ps = strchr (output_secname + 1, '\$');
  592.   *ps = 0;
  593.   os = lang_output_section_statement_lookup (output_secname);
  594.  
  595.   /* Find the '\$' wild statement for this section.  We currently require the
  596.      linker script to explicitly mention "*(.foo\$)".
  597.      FIXME: ppcpe.sc has .CRT\$foo in the .rdata section.  According to the
  598.      Microsoft docs this isn't correct so it's not (currently) handled.  */
  599.  
  600.   ps[0] = '\$';
  601.   ps[1] = 0;
  602.   for (l = os->children.head; l; l = l->next)
  603.     {
  604.       if (l->header.type == lang_wild_statement_enum
  605.       && strcmp (l->wild_statement.section_name, output_secname) == 0)
  606.     break;
  607.     }
  608.   ps[0] = 0;
  609.   if (l == NULL)
  610. #if 1
  611.     einfo ("%P%F: *(%s\$) missing from linker script\n", output_secname);
  612. #else /* FIXME: This block is untried.  It exists to convey the intent,
  613.      should one decide to not require *(.foo\$) to appear in the linker
  614.      script.  */
  615.     {
  616.       lang_wild_statement_type *new = new_stat (lang_wild_statement,
  617.                         &os->children);
  618.       new->section_name = xmalloc (strlen (output_secname) + 2);
  619.       sprintf (new->section_name, "%s\$", output_secname);
  620.       new->filename = NULL;
  621.       lang_list_init (&new->children);
  622.       l = new;
  623.     }
  624. #endif
  625.  
  626.   /* Link the input section in and we're done for now.
  627.      The sections still have to be sorted, but that has to wait until
  628.      all such sections have been processed by us.  The sorting is done by
  629.      sort_sections.  */
  630.   wild_doit (&l->wild_statement.children, s, os, file);
  631.  
  632.   return true;
  633. }
  634.  
  635. static char *
  636. gld_${EMULATION_NAME}_get_script(isfile)
  637.      int *isfile;
  638. EOF
  639. # Scripts compiled in.
  640. # sed commands to quote an ld script as a C string.
  641. sc="-f ${srcdir}/emultempl/stringify.sed"
  642.  
  643. cat >>e${EMULATION_NAME}.c <<EOF
  644. {                 
  645.   *isfile = 0;
  646.  
  647.   if (link_info.relocateable == true && config.build_constructors == true)
  648.     return
  649. EOF
  650. sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
  651. echo '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
  652. sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
  653. echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
  654. sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
  655. echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
  656. sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
  657. echo '  ; else return'                                     >> e${EMULATION_NAME}.c
  658. sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
  659. echo '; }'                                                 >> e${EMULATION_NAME}.c
  660.  
  661. cat >>e${EMULATION_NAME}.c <<EOF
  662.  
  663.  
  664. struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
  665. {
  666.   gld_${EMULATION_NAME}_before_parse,
  667.   syslib_default,
  668.   hll_default,
  669.   after_parse_default,
  670.   gld_${EMULATION_NAME}_after_open,
  671.   after_allocation_default,
  672.   set_output_arch_default,
  673.   ldemul_default_target,
  674.   gld_${EMULATION_NAME}_before_allocation,
  675.   gld_${EMULATION_NAME}_get_script,
  676.   "${EMULATION_NAME}",
  677.   "${OUTPUT_FORMAT}",
  678.   NULL, /* finish */
  679.   NULL, /* create output section statements */
  680.   NULL, /* open dynamic archive */
  681.   gld${EMULATION_NAME}_place_orphan,
  682.   gld_${EMULATION_NAME}_set_symbols,
  683.   gld_${EMULATION_NAME}_parse_args
  684. };
  685. EOF
  686.